package com.proto {
	import com.file.ArgVo;
	import com.file.CFunction;
	import com.file.ClassFile;
	import com.file.ClassType;
	import com.file.asf.ASClassFile;
	import com.file.asf.ASFunction;
	import com.file.asf.ASVar;
	import com.utils.FileUtils;

	/**
	 * 死神项目使用
	 * @author 2018/9/5 星期三 11:45
	 */
	public class MetaProto2 {
		
		public var name:String;
		public var packages:String;
		public var syntax:String;
        public var messages:Array;// Vector.<ProtoMessage>;
        public var enums:Array;// Vector.<ProtoEnum>;
        public var imports:Array;//Vector.<String>;
        public var options:Object;// {[key:String]: any};
        public var services:Array;// Vector.<ProtoService>;
		
		/**
		 * 对应的行
		 */
		public var lines:Object;
		
		public var comments:Object;//所有行注释
		
		public function MetaProto2() {
			
			this.lines = {};
			this.comments = {};
		}
		
		/**
		 * 解析为as文件
		 * @return
		 */
		public function parse2As():Vector.<ASClassFile>{
			
			this.msgMapList = [];			
			this.map = {};
			
			var arr:Vector.<ASClassFile> = new Vector.<ASClassFile>();
			var i:int, j:int, note:String;
			for ( i = 0; i < this.messages.length; i++ ){
				
				var o:Object = this.messages[i];
				o.comment = String( this.comments[ o.line - 1 ] ).replace(/\/|\r/g,"");
				//var isVo:Boolean  = String( o.name ).indexOf("Message") == -1;
				//var isC2S:Boolean = String( o.name ).indexOf("C2S") != -1;
				//var isS2C:Boolean = String( o.name ).indexOf("S2C") != -1;
				
				var asVar:ASVar = null;				
				var asFile:ASClassFile = new ASClassFile( o.name , ClassFile.EXT_AS );
				asFile.pkg = "com.net.protobuf";				
				//声明变量
				for ( j = 0; j < o.fields.length; j++ ){
					
					note = this.comments[ o.fields[j].line ] || this.comments[ o.fields[j].line - 1  ] || ""; //注释	
					var type:String = this.switchAsType( o.fields[j].type );
					if ( o.fields[j].rule == "repeated" ){ //数组
						asVar = asFile.addVar( o.fields[j].name , ClassType.AS_ARRAY , "" , "public" , note ) as ASVar;
					}else if ( 	type == ClassType.AS_NUMBER || type == ClassType.AS_Boolean || 
								type == ClassType.AS_STRING || 
								type == ClassType.AS_INT || type == ClassType.AS_UINT ){
						asVar = asFile.addVar( o.fields[j].name , type , o.fields[j].id , "public" , note ) as ASVar;
					}else{
						asVar = asFile.addVar( o.fields[j].name , type , o.fields[j].id , "public" , note ) as ASVar;
						asFile.addImport( "import com.net.protobuf." + type +";" );
					}
				}
				//类注释
				asFile.classCommonet = this.addNote( "clong" , o.comment ,  1);
				//继承类
				asFile.extendsClass = new ASClassFile( "ProtoMessage" );
				asFile.extendsClass.pkg = "com.net.protobuf";
				if ( asFile.extendsClass.pkg != asFile.pkg ){
					asFile.addImport( "import "+ asFile.extendsClass.pkg + "." + asFile.extendsClass.name+";" );
				}
				//添加引用
				asFile.addImport( "import com.netease.protobuf.ReadUtils;" );
				asFile.addImport( "import com.netease.protobuf.Tag;" );
				asFile.addImport( "import com.netease.protobuf.WireType;" );
				asFile.addImport( "import com.netease.protobuf.WriteUtils;" );
				asFile.addImport( "import flash.utils.IDataInput;" );
				asFile.addImport( "import flash.utils.IDataOutput;" );				
				
				//WriteUtils.writeTag(output, WireType.LENGTH_DELIMITED, 1);
				//WriteUtils.write_TYPE_STRING(output, this.userId );
				//WriteUtils.writeTag(output, WireType.LENGTH_DELIMITED, 2);
				//WriteUtils.write_TYPE_STRING(output, this.userName );
				
				//写数据
				var s1:String = "WriteUtils.writeTag(output, {0}, {1});";
				var s2_0:String = "WriteUtils.write_TYPE_INT32(output, {0} );";
				var s2_1:String = "WriteUtils.write_TYPE_UINT32(output, {0} );";
				var s2_2:String = "WriteUtils.write_TYPE_DOUBLE(output, {0} );";
				var s2_3:String = "WriteUtils.write_TYPE_STRING(output, {0} );";
				var s2_4:String = "WriteUtils.write_TYPE_MESSAGE(output, {0} );";
				
				//while (input.bytesAvailable != 0) {
					//
					//var tag:Tag = ReadUtils.readTag(input);
					//switch (tag.number) {
						//case 1:
							//this.userId = ReadUtils.read_TYPE_STRING(input);
							//break;
						//case 2:
							//this.userName = ReadUtils.read_TYPE_STRING(input);
							//break;
						//default:
							//ReadUtils.skip(input, tag.wireType);
					//}
				//}
				//读数据
				var s3:String = 
				"			while (input.bytesAvailable != 0) {\n"+
				"				var tag:Tag = ReadUtils.readTag(input);\n"+
				"				switch (tag.number) {\n"+
				"					{0}"+
				"					default:\n"+
				"						ReadUtils.skip(input, tag.wireType);\n"+
				"				}\n"+
				"			}";
				var s4:String = 
							"					case {0}:\n"+
							"						{1}\n"+
							"						break;\n";
				var s5:String = "";
				
				var ProtoMessage:ASClassFile = this.getProtoMessage();//如果不行注释掉
				var vec1:Vector.<ArgVo> = new Vector.<ArgVo>();
				vec1.push( new ArgVo("output", "IDataOutput") );
				var cf1:ASFunction = new ASFunction( "writeExternal" , vec1 , ProtoMessage );	
				cf1.desc = "写入数据";
				for (j = 0; j < asFile.globalVars.length;j++ ){
					asVar = asFile.globalVars[j] as ASVar;
					if (!asVar || asVar.isMsgId){
						continue;
					}
					if ( asVar.isInt ){
						cf1.content += "\t\t\t"+replaceHolder( s1 , ["WireType.VARINT", asVar.value] ) + "\n";	
						cf1.content += "\t\t\t"+replaceHolder( s2_0 , ["this." + asVar.name] )+ "\n\n";//WriteUtils.write_TYPE_INT32
						
						s5 += replaceHolder( s4 , [asVar.value,"this."+asVar.name+" = ReadUtils.read_TYPE_INT32(input);"] )+ "\n";
					}else if ( asVar.isUint ){
						cf1.content += "\t\t\t"+replaceHolder( s1 , ["WireType.VARINT", asVar.value] ) + "\n";	
						cf1.content += "\t\t\t"+replaceHolder( s2_1 , ["this." + asVar.name] )+ "\n\n";//WriteUtils.write_TYPE_UINT32
						
						s5 += replaceHolder( s4 , [asVar.value,"this."+asVar.name+" = ReadUtils.read_TYPE_UINT32(input);"] )+ "\n";
					}else if ( asVar.isNumber ){
						cf1.content += replaceHolder( s1 , ["WireType.VARINT", asVar.value] ) + "\n";	
						cf1.content += replaceHolder( s2_2 , ["this." + asVar.name] )+ "\n\n";//WriteUtils.write_TYPE_DOUBLE
						
						s5 += replaceHolder( s4 , [asVar.value,"this."+asVar.name+" = ReadUtils.read_TYPE_DOUBLE(input);"] )+ "\n";
					}else if (asVar.isString){
						cf1.content += "\t\t\t"+replaceHolder( s1 , ["WireType.LENGTH_DELIMITED", asVar.value] ) + "\n";
						cf1.content += "\t\t\t"+replaceHolder( s2_3 , ["this." + asVar.name] )+ "\n\n";//WriteUtils.write_TYPE_STRING
						
						s5 += replaceHolder( s4 , [asVar.value,"this."+asVar.name+" = ReadUtils.read_TYPE_STRING(input);"] )+ "\n";
					}else if (asVar.isArray){ //数组
						cf1.content += "\t\t\tfor (var i:uint = 0; i < this." + asVar.name+".length; ++i){"
						if (asVar.isUint || asVar.isInt || asVar.isNumber ){
							cf1.content += "\t\t\t\t" + replaceHolder( s1 , ["WireType.VARINT", asVar.value ] ) + "\n";
							if (asVar.isInt){
								cf1.content += "\t\t\t\t"+replaceHolder( s2_0 , ["this." + asVar.name+"[i]"] )+ "\n\n";
							}else if ( asVar.isUint ){
								cf1.content += "\t\t\t\t"+replaceHolder( s2_1 , ["this." + asVar.name+"[i]"] )+ "\n\n";
							}else if ( asVar.isNumber ){
								cf1.content += "\t\t\t\t"+replaceHolder( s2_2 , ["this." + asVar.name+"[i]"] )+ "\n\n";
							}				
							
							s5 += replaceHolder( s4 , [asVar.value,"this."+asVar.name+".push( ReadUtils.read_TYPE_UINT32(input) );"] )+ "\n";
						}else if ( asVar.isString ){
							cf1.content += "\t\t\t\t" + replaceHolder( s1 , ["WireType.LENGTH_DELIMITED", asVar.value ] ) + "\n";
							cf1.content += "\t\t\t\t" + replaceHolder( s2_3 , ["this." + asVar.name] ) + "\n\n";//WriteUtils.write_TYPE_STRING
							
							s5 += replaceHolder( s4 , [asVar.value,"this."+asVar.name+".push( ReadUtils.read_TYPE_STRING(input) );"] )+ "\n";
						}else{
							
							s5 += replaceHolder( s4 , [asVar.value,"this."+asVar.name+".push( ReadUtils.read_TYPE_MESSAGE( input , new "+asVar.type+"() ) as "+asVar.type+" );"] )+ "\n";
						}
						cf1.content += "\t\t\t}";
						
					}else{//其他数据
						cf1.content += "\t\t\t"+replaceHolder( s1 , ["WireType.LENGTH_DELIMITED", asVar.value] ) + "\n";
						cf1.content += "\t\t\t"+replaceHolder( s2_4 , ["this." + asVar.name] )+ "\n\n";//WriteUtils.write_TYPE_MESSAGE
						
						s5 += replaceHolder( s4 , [asVar.value,"this."+asVar.name+" = ReadUtils.read_TYPE_MESSAGE( input , new "+asVar.type+"() ) as "+asVar.type+";"] )+ "\n";
					}					
				}
				cf1.power = "public";
				asFile.addFunc( cf1 );
				
				//读数据
				var vec2:Vector.<ArgVo> = new Vector.<ArgVo>();
				vec2.push( new ArgVo("input", "IDataInput") );//,null,ProtoMessage
				
				var cf2:ASFunction = new ASFunction( "readExternal" , vec2 , ProtoMessage );
				cf2.desc = "读取数据";
				cf2.content += replaceHolder( s3 , ["\n" + s5] );
				cf2.power = "public";
				asFile.addFunc( cf2);
				
				arr.push(asFile);
			}
			
			return arr;
		}
		
		/**
		 * ProtoMessage 类文件
		 */
		private function getProtoMessage():ASClassFile{
			
			var argVos:Vector.<ArgVo> = new Vector.<ArgVo>;
			argVos.push( new ArgVo("output","IDataOutput") );
			
			var argVos2:Vector.<ArgVo> = new Vector.<ArgVo>;
			argVos2.push( new ArgVo("input","IDataInput") );
			
			var file:ASClassFile = new ASClassFile( "ProtoMessage" );
			file.addFunc( new CFunction("writeExternal" , argVos ) );
			file.addFunc( new CFunction("readExternal" , argVos2 ) );
			return file;
		}
		
		/**
		 * 替换占位符 2012.11.15
		 * @param	str 字符串中含占位符，如: xxx{0}xxx{1}
		 * @param	arr
		 * @return
		 */
		private static function replaceHolder(str:String, arr:Array = null):String {
			
			if (arr) {
				
				var ind:int;
				var temp:String;
				
				str = str.replace(/\{[0-9]\}/g, function():String {
					
					temp = arguments[0].replace(/\{/g, "")
					ind = int(temp.replace(/\}/g, ""));
					
					return arr[ind];
				});
			}
			return str;
		}
		
		/**
		 * 获取构造函数内容
		 * @param	o
		 * @return
		 */
		private function getConstructor( o:Object ):String{
			
			var j:int = 0;
			var tNum:int = 2;
			var arr1:Array = [];
			arr1.push( "\n"+ FileUtils.copyChar( "\t" , tNum + 1 ) + "if( value!=null ){" );
			for (j = 0; j < o.fields.length; j++ ){
				if ( o.fields[j].rule == "repeated" ){ //数组							
					if ( this.isLong( o.fields[j].type ) ){
						arr1.push( FileUtils.copyChar( "\t" , tNum + 2 ) + "this." + o.fields[j].name + " = Long.fromValue(value." + o.fields[j].name + ");");
					}else if( this.isNumber( o.fields[j].type ) || isBoolean( o.fields[j].type ) || isString( o.fields[j].type ) ){
						arr1.push( FileUtils.copyChar( "\t" , tNum + 2 ) + "this." + o.fields[j].name + " = value." + o.fields[j].name + ";" );
					}else{
						arr1.push( FileUtils.copyChar( "\t" , tNum + 2 ) + "this." + o.fields[j].name+" = [];"  );
						arr1.push( FileUtils.copyChar( "\t" , tNum + 2 ) + "for (var i: int = 0; i < this.data."+o.fields[j].name+".length; i++) {"  );
						arr1.push( FileUtils.copyChar( "\t" , tNum + 3 ) + "this." + o.fields[j].name + ".push( new "+o.fields[j].type+"(value." + o.fields[j].name + "[i]));" );
						arr1.push( FileUtils.copyChar( "\t" , tNum + 2 ) + "}"  );
					}
				}else{//非数组
					if ( this.isLong( o.fields[j].type ) ){
						arr1.push( FileUtils.copyChar( "\t" , tNum + 2 ) + "this." + o.fields[j].name + " = Long.fromValue(value." + o.fields[j].name + ");");
					}else if( this.isNumber( o.fields[j].type ) || isBoolean( o.fields[j].type ) || isString( o.fields[j].type ) ){
						arr1.push( FileUtils.copyChar( "\t" , tNum + 2 ) + "this." + o.fields[j].name + " = value." + o.fields[j].name + ";" );
					}else{
						arr1.push( FileUtils.copyChar( "\t" , tNum + 2 ) + "this." + o.fields[j].name + " = new "+o.fields[j].type+"(value." + o.fields[j].name + ");" );
					}
				}						
			}
			arr1.push( FileUtils.copyChar( "\t" , tNum + 1 ) + "}" );
			return arr1.join("\n");
		}
		
		private var msgMapList:Array = [];
		//解析成对应的TS文件
		public var map:Object = {};
		/**解析为ts文件**/
		public function parse2Ts():Array{
			
			this.msgMapList = [];
			map = {};			
			var arr:Array = [];
			for ( var i:int = 0; i < this.messages.length; i++ ){
				var o:Object = this.messages[i];
				var arr1:Array = [];
				var arr2:Array = [];
				var tNum:int = 1;//当前\t注释数量
				var isVo:Boolean  = String( o.name ).indexOf("Message") == -1;
				var isC2S:Boolean = String( o.name ).indexOf("C2S") != -1;
				//var packages:String = "module " + ( this.packages || "net" ) + "{";			
				var packages:String = "module net{";			
				arr1.push( packages );
				arr2.push( "}" );
				
				arr1.push( this.addNote( "cl" , "自动生成请勿修改" ,  tNum) );
				trace("测试名字: " + o.name);
				if ( o.name == "S2C_RechargeGoodsInfoMessage" ){
					trace("测试名字: " + o.name);
				}
				var j:int = 0;
				var note:String;
				var field:String;
				if (isVo){ //Vo类型
					arr1.push( FileUtils.copyChar( "\t" , tNum ) + "export class " + o.name + "{\n");
					arr2.unshift( FileUtils.copyChar( "\t" , tNum ) + "}" );
					tNum++;
					
					//声明变量
					for ( j = 0; j < o.fields.length; j++ ){
						
						note = this.comments[ o.fields[j].line ] || this.comments[ o.fields[j].line - 1  ] || ""; //注释						
						if ( o.fields[j].rule == "repeated" ){ //数组
							field = "public " + o.fields[j].name + ":<" + switchTsType( o.fields[j].type ) + ">;" + note;
						}else{
							field = "public " + o.fields[j].name + ":" + switchTsType( o.fields[j].type ) + ";" + note;
						}						
						arr1.push( FileUtils.copyChar( "\t" , tNum ) + field );
					}
					
					//构造函数 				
					arr1.push( "\n" + FileUtils.copyChar( "\t" , tNum ) + "public constructor(value?:any){" );
					arr1.push( FileUtils.copyChar( "\t" , tNum + 1 ) + "if(value){" );
					for (j = 0; j < o.fields.length; j++ ){
						if ( o.fields[j].rule == "repeated" ){ //数组							
							if ( this.isLong( o.fields[j].type ) ){
								arr1.push( FileUtils.copyChar( "\t" , tNum + 2 ) + "this." + o.fields[j].name + " = Long.fromValue(value." + o.fields[j].name + ");");
							}else if( this.isNumber( o.fields[j].type ) || isBoolean( o.fields[j].type ) || isString( o.fields[j].type ) ){
								arr1.push( FileUtils.copyChar( "\t" , tNum + 2 ) + "this." + o.fields[j].name + " = value." + o.fields[j].name + ";" );
							}else{
								arr1.push( FileUtils.copyChar( "\t" , tNum + 2 ) + "this." + o.fields[j].name+" = [];"  );
								arr1.push( FileUtils.copyChar( "\t" , tNum + 2 ) + "for (let i: number = 0; i < this.data."+o.fields[j].name+".length; i++) {"  );
								arr1.push( FileUtils.copyChar( "\t" , tNum + 3 ) + "this." + o.fields[j].name + ".push( new "+o.fields[j].type+"(value." + o.fields[j].name + "[i]));" );
								arr1.push( FileUtils.copyChar( "\t" , tNum + 2 ) + "}"  );
							}
						}else{//非数组
							if ( this.isLong( o.fields[j].type ) ){
								arr1.push( FileUtils.copyChar( "\t" , tNum + 2 ) + "this." + o.fields[j].name + " = Long.fromValue(value." + o.fields[j].name + ");");
							}else if( this.isNumber( o.fields[j].type ) || isBoolean( o.fields[j].type ) || isString( o.fields[j].type ) ){
								arr1.push( FileUtils.copyChar( "\t" , tNum + 2 ) + "this." + o.fields[j].name + " = value." + o.fields[j].name + ";" );
							}else{
								arr1.push( FileUtils.copyChar( "\t" , tNum + 2 ) + "this." + o.fields[j].name + " = new "+o.fields[j].type+"(value." + o.fields[j].name + ");" );
							}
						}						
					}
					arr1.push( FileUtils.copyChar( "\t" , tNum + 1) + "}" );
					arr1.push( FileUtils.copyChar( "\t" , tNum ) + "}" );					
					tNum++;
				}else{ //Message类型
					arr1.push( FileUtils.copyChar( "\t" , tNum ) + "export class " + o.name + " extends Message{\n");
					arr2.unshift( FileUtils.copyChar( "\t" , tNum ) + "}" );
					tNum++;
					
					//声明变量
					for ( j = 0; j < o.fields.length; j++ ){						
						note = this.comments[ o.fields[j].line ] || this.comments[ o.fields[j].line - 1  ] || ""; //注释						
						if ( o.fields[j].rule == "repeated" ){ //数组
							field = "public " + o.fields[j].name + ":<" + switchTsType( o.fields[j].type ) + ">;" + note;
						}else{
							field = "public " + o.fields[j].name + ":" + switchTsType( o.fields[j].type ) + ";" + note;
						}
						arr1.push( FileUtils.copyChar( "\t" , tNum ) + field );
					}
					
					//构造函数 				
					arr1.push( "\n" + FileUtils.copyChar( "\t" , tNum ) + "public constructor(){" );
					arr1.push( FileUtils.copyChar( "\t" , tNum + 1 ) + "super();" );
					arr1.push( FileUtils.copyChar( "\t" , tNum + 1 ) + "this.className = '" + o.name + "';" );
					arr1.push( FileUtils.copyChar( "\t" , tNum ) + "}" );
					
					if ( isC2S ){
						//parseData 方法解析
						arr1.push( "\n" + this.addNote( "" , "" ,  tNum) );
						arr1.push( FileUtils.copyChar( "\t" , tNum ) + "public parseData():void{" );
						arr1.push( FileUtils.copyChar( "\t" , tNum + 1 ) + "super.parseData();" );
						for (j = 0; j < o.fields.length; j++ ){
							//if ( o.fields[j].rule == "repeated" ){ //是否为数组
								//trace("发送消息为数组");
							//}
							if ( isLong( o.fields[j].type ) ){
								arr1.push( FileUtils.copyChar( "\t" , tNum + 1 ) + "if(Long.isLong(this." + o.fields[j].name+")){"  );
								arr1.push( FileUtils.copyChar( "\t" , tNum + 2 ) + "this.data." + o.fields[j].name + " = this." + o.fields[j].name + ".toString();");
								arr1.push( FileUtils.copyChar( "\t" , tNum + 1 ) + "}");
							}else if ( isNumber( o.fields[j].type ) ){
								arr1.push( FileUtils.copyChar( "\t" , tNum + 1 ) + "if(!NaN(this." + o.fields[j].name+")){"  );
								arr1.push( FileUtils.copyChar( "\t" , tNum + 2 ) + "this.data." + o.fields[j].name + " = this." + o.fields[j].name + ";");
								arr1.push( FileUtils.copyChar( "\t" , tNum + 1 ) + "}");
							}else if (switchTsType(o.fields[j].type) == "boolean"){
								arr1.push( FileUtils.copyChar( "\t" , tNum + 1 ) + "this.data." + o.fields[j].name + " = this." + o.fields[j].name + ";");
							}else{
								arr1.push( FileUtils.copyChar( "\t" , tNum + 1 ) + "if(this.data." + o.fields[j].name+"){"  );
								arr1.push( FileUtils.copyChar( "\t" , tNum + 2 ) + "this.data." + o.fields[j].name + " = this." + o.fields[j].name + ";");
								arr1.push( FileUtils.copyChar( "\t" , tNum + 1 ) + "}");
							}
						}
						arr1.push( FileUtils.copyChar( "\t" , tNum ) + "}" );
					}else{ //S2C
						//parseMsg 方法解析
						arr1.push( "\n" + this.addNote("" , "" ,  tNum) );// "@description 解析数据,当收到消息的时候调用" , 
						arr1.push( FileUtils.copyChar( "\t" , tNum ) + "public parseMsg(dataBuff: ArrayBuffer):void{" );
						arr1.push( FileUtils.copyChar( "\t" , tNum + 1 ) + "super.parseMsg(dataBuff);" );
						for (j = 0; j < o.fields.length; j++ ){
							if ( o.fields[j].rule == "repeated" ){ //如果是数组
								arr1.push( FileUtils.copyChar( "\t" , tNum + 1 ) + "this." + o.fields[j].name+" = [];"  );
								if ( this.isLong( o.fields[j].type ) ){ //Long
									//arr1.push( FileUtils.copyChar( "\t" , tNum + 1 ) + "if(Long.isLong(this." + o.fields[j].name+")){"  );
									//arr1.push( FileUtils.copyChar( "\t" , tNum + 2 ) + "this." + o.fields[j].name + " = this.data." + o.fields[j].name + ".toString();");
									//arr1.push( FileUtils.copyChar( "\t" , tNum + 1 ) + "}");
									arr1.push( FileUtils.copyChar( "\t" , tNum + 1 ) + "if(this.data." + o.fields[j].name+"){"  );
									arr1.push( FileUtils.copyChar( "\t" , tNum + 2 ) + "for (let i: number = 0; i < this.data."+o.fields[j].name+".length; i++) {"  );
									arr1.push( FileUtils.copyChar( "\t" , tNum + 3 ) + "if(Long.isLong(this." + o.fields[j].name+")){"  );
									arr1.push( FileUtils.copyChar( "\t" , tNum + 4 ) + "this." + o.fields[j].name + ".push( this.data." + o.fields[j].name + ".toString() );");
									arr1.push( FileUtils.copyChar( "\t" , tNum + 3 ) + "}");
									arr1.push( FileUtils.copyChar( "\t" , tNum + 2 ) + "}"  );
									arr1.push( FileUtils.copyChar( "\t" , tNum + 1 ) + "}"  );
								}else if ( this.isNumber( o.fields[j].type ) ){ //number
									//arr1.push( FileUtils.copyChar( "\t" , tNum + 1 ) + "if(!NaN(this." + o.fields[j].name+")){"  );
									//arr1.push( FileUtils.copyChar( "\t" , tNum + 2 ) + "this." + o.fields[j].name + " = this.data." + o.fields[j].name + ";");
									//arr1.push( FileUtils.copyChar( "\t" , tNum + 1 ) + "}");
									arr1.push( FileUtils.copyChar( "\t" , tNum + 1 ) + "if(this.data." + o.fields[j].name+"){"  );
									arr1.push( FileUtils.copyChar( "\t" , tNum + 2 ) + "for (let i: number = 0; i < this.data."+o.fields[j].name+".length; i++) {"  );
									arr1.push( FileUtils.copyChar( "\t" , tNum + 3 ) + "if(!NaN(this." + o.fields[j].name+")){"  );
									arr1.push( FileUtils.copyChar( "\t" , tNum + 4 ) + "this." + o.fields[j].name + ".push(this.data." + o.fields[j].name + "[i]);");
									arr1.push( FileUtils.copyChar( "\t" , tNum + 3 ) + "}");
									arr1.push( FileUtils.copyChar( "\t" , tNum + 2 ) + "}"  );
									arr1.push( FileUtils.copyChar( "\t" , tNum + 1 ) + "}"  );
								}else if ( this.isBoolean(o.fields[j].type) || this.isString(o.fields[j].type) ){//boolean string
									arr1.push( FileUtils.copyChar( "\t" , tNum + 1 ) + "if(this.data." + o.fields[j].name+"){"  );
									arr1.push( FileUtils.copyChar( "\t" , tNum + 2 ) + "for (let i: number = 0; i < this.data."+o.fields[j].name+".length; i++) {"  );
									arr1.push( FileUtils.copyChar( "\t" , tNum + 3 ) + "this." + o.fields[j].name + ".push( this.data." + o.fields[j].name + "[i]);");
									arr1.push( FileUtils.copyChar( "\t" , tNum + 2 ) + "}"  );
									arr1.push( FileUtils.copyChar( "\t" , tNum + 1 ) + "}"  );
								}else{									
									arr1.push( FileUtils.copyChar( "\t" , tNum + 1 ) + "if(this.data." + o.fields[j].name+"){"  );
									arr1.push( FileUtils.copyChar( "\t" , tNum + 2 ) + "for (let i: number = 0; i < this.data."+o.fields[j].name+".length; i++) {"  );
									arr1.push( FileUtils.copyChar( "\t" , tNum + 3 ) + "this."+o.fields[j].name+".push(new " + o.fields[j].type + "(this.data."+o.fields[j].name+"[i]));"  );
									arr1.push( FileUtils.copyChar( "\t" , tNum + 2 ) + "}"  );
									arr1.push( FileUtils.copyChar( "\t" , tNum + 1 ) + "}"  );
								}
							}else{ //不是数组的处理方式
								if ( this.isLong( o.fields[j].type ) ){ //Long
									arr1.push( FileUtils.copyChar( "\t" , tNum + 1 ) + "if(Long.isLong(this." + o.fields[j].name+")){"  );
									arr1.push( FileUtils.copyChar( "\t" , tNum + 2 ) + "this." + o.fields[j].name + " = this.data." + o.fields[j].name + ".toString();");
									arr1.push( FileUtils.copyChar( "\t" , tNum + 1 ) + "}");
								}else if ( this.isNumber( o.fields[j].type ) ){ //number
									arr1.push( FileUtils.copyChar( "\t" , tNum + 1 ) + "if(!NaN(this." + o.fields[j].name+")){"  );
									arr1.push( FileUtils.copyChar( "\t" , tNum + 2 ) + "this." + o.fields[j].name + " = this.data." + o.fields[j].name + ";");
									arr1.push( FileUtils.copyChar( "\t" , tNum + 1 ) + "}");
								}else if ( this.isBoolean(o.fields[j].type) || this.isString(o.fields[j].type) ){//boolean string
									arr1.push( FileUtils.copyChar( "\t" , tNum + 1 ) + "this." + o.fields[j].name + " = this.data." + o.fields[j].name + ";");
								}else{
									arr1.push( FileUtils.copyChar( "\t" , tNum + 1 ) + "if(this.data." + o.fields[j].name+"){"  );
									arr1.push( FileUtils.copyChar( "\t" , tNum + 2 ) + "this." + o.fields[j].name + " = new " + o.fields[j].type + "(this.data."+o.fields[j].name+");");
									arr1.push( FileUtils.copyChar( "\t" , tNum + 1 ) + "}");
								}
							}							
						}
						arr1.push( FileUtils.copyChar( "\t" , tNum ) + "}" );
					}
					
					tNum++;
				}
				
				arr1 = arr1.concat( arr2 );
				var str:String = arr1.join("\n");
				var path:String = "net";// this.packages || "com.net.vo";
				path = path.replace(/\./g,"/");
				arr.push( {"name":o.name, "text":str , "path":path} );
				trace( "--------------" + o.name );
				trace( str );
				
				map[ o.name ] = {"name":o.name, "text":str , "path":path, "vo":isVo};
				
				//用于生成
				if ( !isVo ){
					var msgId:int = Proto2TsUtils.getMsgId( o.name );
					if ( msgId > 0 ){
						this.msgMapList.push( {"msgId":msgId , "name":o.name} );
					}
				}
			}
			
			map[ "MessagePool" ] = {"name":"MessagePool", "text":this.makeProtoMsgFile( this.msgMapList ) , "path":"com/net","vo":false}; 
			
			return arr;
		}
		
		/**
		 * MessagePool.ts
		 * @param	obj
		 * @return
		 */
		private function makeProtoMsgFile( msgMapList:Array ):String{
			
			var arr1:Array = [];
			var arr2:Array = [];
			//var packages:String = "module " + ( this.packages || "com.net" ) + "{";		
			var packages:String = "module MessagePool{";		
			arr1.push( packages );
			
			arr1.push( this.addNote("cl" , "自动生成请勿修改" ,  1) );// "消息池" , 
			arr1.push( FileUtils.copyChar( "\t" , 1 ) + "export class MessagePool implements IMessagePool {");	
			
			arr1.push( FileUtils.copyChar( "\t" , 2 ) + "private messages: flash.Dictionary = new flash.Dictionary();");
			arr1.push( FileUtils.copyChar( "\t" , 2 ) + "private messageClass: flash.Dictionary = new flash.Dictionary();");
			arr1.push( FileUtils.copyChar( "\t" , 2 ) + "public MSG_VER_STR: string = \""+FileUtils.DateToString( new Date() )+"\";");
			arr1.push( FileUtils.copyChar( "\t" , 2 ) + "public MSG_VER_NUM: number = "+1532587648+";");
			
			arr1.push( FileUtils.copyChar( "\t" , 2 ) + "public constructor(){");
			arr1.push( FileUtils.copyChar( "\t" , 3 ) + "let _self__: MessagePool = this;");
			var i:int = 0;
			var o:Object = null;
			for (i = 0; i < msgMapList.length; i++ ){
				o = msgMapList[i];
				
				arr1.push( FileUtils.copyChar( "\t" , 3 ) + "_self__.register("+o.msgId+", net."+o.msgId+", 0, 100);");				
			}
			arr1.push(FileUtils.copyChar( "\t" , 2 ) + "}");	
			
			arr1.push( FileUtils.copyChar( "\t" , 2 ) + "public getMsg(id:string):string{");
			arr1.push( FileUtils.copyChar( "\t" , 3 ) + "return this.msgIdMap[id];");
			arr1.push( FileUtils.copyChar( "\t" , 2 ) + "}");
			
			//arr1.push(FileUtils.copyChar( "\t" , 1 ) + "}");			
			arr1.push(FileUtils.copyChar( "\t" , 1 ) + "}");
			arr1.push("}");
			var str:String = arr1.join("\n");
			//trace("" + str);
			return str;
		}
		
		public function getTs( cls:String ):String{
			
			return map[ cls ] || "";
		}
		
		private function isNumber( type:String ):Boolean{
			
			return this.switchTsType(type) == "number" || this.switchAsType(type) == ClassType.AS_NUMBER;
		}
		
		private function isLong( type:String ):Boolean{
			
			return this.switchTsType(type) == "Long";
		}
		
		private function isString( type:String ):Boolean{
			
			return this.switchTsType(type) == "string" || this.switchAsType(type) == ClassType.AS_STRING;
		}
		
		private function isBoolean( type:String ):Boolean{
			
			return this.switchTsType(type) == "boolean" || this.switchAsType(type) == ClassType.AS_Boolean;
		}
		
		/**
		 * 是否为自定义类
		 * @param	type
		 * @return
		 */
		public function isSelf( type:String ):Boolean{
			
			return !(this.isNumber( type ) || this.isBoolean(type) || this.isString(type) || this.isLong(type) );
		}
		
		private function switchTsType( type:String ):String{
			
			switch( type ){
				
				case "int64":
					return "Long";
					break;
				
				case "uint32":
				case "sint32":				
				case "uint64":
				case "sint64":
				case "bytes":
				case "double":
				case "int32":
				case "float":
				case "sfixed64":
				case "fixed64":
					return "number";
					break;
				case "bool":
					return "boolean";
					break;
				case "string":
					return "string";
					break;
			}
			return type;
		}
		
		private function switchAsType( type:String ):String{
			
			switch( type ){
				
				case "int32":
				case "int64":
					return "int";
					break;
				
				case "uint64":
				case "uint32":				
					return "uint";
					break;
				
								
				case "sint32":					
				case "sint64":
				case "bytes":
				case "double":				
				case "float":
				case "sfixed64":
				case "fixed64":
					return "Number";
					break;
					
				case "bool":
					return "Boolean";
					break;
					
				case "string":
					return "String";
					break;
			}
			return type;
		}
		
		/**
		 * 用于生成一个注释
		 * @param	func
		 * @param	author
		 * @param	date
		 * @param	desc
		 * @return
		 */
		private function addNote( author:String = "cl" , desc:String = "" , tn:int = 0 ):String{
			
			var tnstr:String = FileUtils.copyChar( "\t" , tn );			
			var str:String  = tnstr + "/**\n";
			if ( desc ){
				str			+= tnstr + " * " + desc + "\n";
			}	
			str 		   += tnstr + " * 通过ATTool工具导入*.proto文件后自动生成\n";
			if (author){
				str			+= tnstr + " * @author " + author + "  " + FileUtils.DateToString( new Date() ) + "\n";
			}					
			str			   += tnstr + " */";
			return str;
		}		
	}
}